<template>
    <div id='AddBlog'>
        <!-- 面包屑导航 -->
        <el-breadcrumb separator-class="el-icon-arrow-right">
            <el-breadcrumb-item :to="{ path: '/admin' }">首页</el-breadcrumb-item>
            <el-breadcrumb-item>博客管理</el-breadcrumb-item>
            <el-breadcrumb-item>写博客</el-breadcrumb-item>
        </el-breadcrumb>
        <!-- 卡片视图区域 -->
        <el-card :body-style="{ padding: 0 }">
            <!-- 搜索与添加区域 -->
            <div slot="header">
                <el-row type="flex" justify="space-between">
                    <el-col :span="17">
                        <el-input class="input-title" type="text" placeholder="请输入标题" v-model="postForm.title"
                                  maxlength="50"
                                  show-word-limit>
                        </el-input>
                    </el-col>
                    <el-col :span="2">
                        <el-button @click="addBlog('editor', false)">保存草稿</el-button>
                    </el-col>
                    <el-col :span="2">
                        <el-button type="primary" @click="imgDialogVisible = true">首图摘要</el-button>
                    </el-col>
                    <el-col :span="2">
                        <el-button type="danger" @click="postBlogDialog">发布文章</el-button>
                    </el-col>
                </el-row>
            </div>
            <div id="editor">
                <mavon-editor ref="editor" @save="saveEditor" v-model="postForm.content" class="tl-height-100-percent"
                              :tabSize="4" codeStyle="atom-one-dark"
                              :boxShadow="false"></mavon-editor>
            </div>
        </el-card>
        <el-dialog title="添加首图摘要" :visible.sync="imgDialogVisible" :close-on-click-modal="false">
            <el-form ref="imgRef" label-width="90px" label-suffix=":">
                <el-form-item label="文章首图">
                    <el-input v-model="postForm.firstPicture" placeholder="首图引用地址"></el-input>
                    <el-upload class="tl-margin-top-20" list-type="picture-card"
                               action="http://127.0.0.1:8888/api/private/v1/upload/"
                               :on-preview="handlePictureCardPreview"
                               :on-remove="handleRemove"
                               :limit="1"
                               :on-success="handleAvatarSuccess"
                               :before-upload="beforeAvatarUpload" :file-list="fileList">
                        <i class="el-icon-plus avatar-uploader-icon"></i>
                    </el-upload>
                </el-form-item>
                <el-form-item label="文章摘要">
                    <el-input type="textarea" v-model="postForm.description"></el-input>
                </el-form-item>
            </el-form>
            <el-dialog top="3%" width="40%" :visible.sync="image_pre_vis" append-to-body>
                <img width="100%" :src="postForm.firstPicture" alt="">
            </el-dialog>
        </el-dialog>
        <!-- 发布文章 -->
        <el-dialog top="2vh" width="40%" title="发布文章" :visible.sync="postDialogVisible" :close-on-click-modal="false">
            <el-form ref="postRef" :rules="addFormRules" :model="postForm" label-width="90px" label-suffix=":">
                <el-form-item label="文章标签">
                    <el-tag :key="tag" v-for="tag in postForm.tags" @close="handleClose(postForm.tags, tag)" closable>
                        {{ tag }}
                    </el-tag>
                    <el-input class="input-new-tag" v-if="tagInputVisible" v-model="tagInputValue" ref="saveTagInput"
                              size="small"
                              @keyup.enter.native="handleInputConfirm('tag')" @blur="handleInputConfirm('tag')">
                    </el-input>
                    <el-button v-else-if="!disable(postForm.tags, 5)" class="button-new-tag" size="small"
                               @click="showInput('tag')">+ 添加文章标签
                    </el-button>
                    <span v-else class="tl-color-red tl-font-12-px tl-text-no-select">*最多只能添加5个标签！</span>
                </el-form-item>
                <el-form-item label="文章分类">
                    <el-tag :key="type.id" v-for="type in postForm.types" @close="handleClose(postForm.types, type)"
                            closable>
                        {{ JSON.parse(type).name }}
                    </el-tag>
                    <el-input class="input-new-tag" v-if="cateInputVisible" v-model="cateInputValue" ref="saveCateInput"
                              size="small" @keyup.enter.native="handleInputConfirm('cate')"
                              @blur="handleInputConfirm('cate')">
                    </el-input>
                    <el-button v-else-if="!disable(postForm.types, 3)" class="button-new-tag" size="small"
                               @click="showInput('cate')">+ 添加文章分类
                    </el-button>
                    <el-card class="cate-card tl-overflow-hidden" shadow="never">
                        <div slot="header">
                            <span>最多选择3个文章分类</span>
                        </div>
                        <div style="height:150px; overflow: auto;">
                            <el-checkbox-group v-model="postForm.types">
                                <el-checkbox v-for="cate in cateBoxList" :key="cate.id" :label="JSON.stringify(cate)">
                                    {{ cate.name }}
                                </el-checkbox>
                            </el-checkbox-group>
                            <div class="el-loading-mask" v-if="disable(postForm.types, 3)">
                                <div class="el-loading-spinner">
                                    <i class="el-icon-remove-outline"></i>
                                    <p class="el-loading-text">最多选三个分类哦~</p>
                                </div>
                            </div>
                        </div>
                    </el-card>
                </el-form-item>
                <el-form-item prop="flag" label="文章类型">
                    <el-select v-model="postForm.flag" placeholder="请选择" clearable>
                        <el-option label="原创" value="original"></el-option>
                        <el-option label="转载" value="repost"></el-option>
                        <el-option label="翻译" value="translated"></el-option>
                    </el-select>
                    <div class="tl-margin-top-10"
                         v-if="postForm.flag === 'repost' || postForm.flag === 'translated'">
                        <el-input :class="{'tl-width-95-percent': postForm.flag === 'repost'}"
                                  v-model="original_link" placeholder="请填写原文链接"></el-input>
                        <span v-if="postForm.flag === 'repost'"
                              class="tl-color-red tl-font-12-px tl-text-no-select tl-margin-left-5">*</span>
                    </div>
                </el-form-item>
                <el-form-item label="发布形式">
                    <el-radio-group v-model="postForm.published">
                        <el-radio label="public">公开</el-radio>
                        <el-radio label="private">私密</el-radio>
                    </el-radio-group>
                </el-form-item>
            </el-form>
            <span slot="footer" class="dialog-footer">
                <el-button size="medium" @click="postDialogVisible = false">取消</el-button>
                <el-button size="medium" type="primary" @click="addBlog('postRef', false)">保存为草稿</el-button>
                <el-button size="medium" type="danger" @click="addBlog('postRef', true)">发布文章</el-button>
            </span>
        </el-dialog>
    </div>
</template>

<script>
import _ from 'lodash'
import { mavonEditor } from 'mavon-editor'
import 'mavon-editor/dist/css/index.css'

export default {
    name: 'AddBlog',
    components: { mavonEditor },
    data: function () {
        return {
            checkSave: 3,
            postDialogVisible: false,
            imgDialogVisible: false,
            addFormRules: {
                flag: [{
                    type: 'string', required: true, message: '请选择文章类型', trigger: 'change'
                }]
            },
            postForm: {
                userId: '',
                title: '',
                published: 'public',
                content: '',
                render: '',
                firstPicture: '',
                tags: [],
                types: [],
                flag: '',
                status: false,
                description: ''
            },
            cateBoxList: [],
            tagInputVisible: false,
            tagInputValue: '',
            cateInputVisible: false,
            cateInputValue: '',
            original_link: '',
            imageUrl: '',
            image_pre_vis: false,
            fileList: [],
            handbook: ''
        }
    },
    methods: {
        postBlogDialog: function () {
            this.postDialogVisible = true
            this.getTypeList()
        },
        getTypeList: async function () {
            const { data: res } = await this.$http.get('/types/list');
            if (res.code ^ 200) {
                return this.$message({ showClose: true, message: res.msg, type: 'error' });
            }
            console.log(res)
            this.cateBoxList = res.data;
        },
        getBlog: async function () {
            let url
            if (typeof (this.$route.query.id) === 'undefined') {
                url = '/blog/draft'
            } else {
                url = `/blog/draft/${this.$route.query.id}`
            }
            console.log(url)
            const { data: res } = await this.$http.get(url);
            console.log(res)
            if (res.code ^ 200) {
                return this.$message({ showClose: true, message: res.msg, type: 'error' });
            }
            this.postForm = res.data;
            for (let i = 0; i < this.postForm.types.length; i++) {
                if (Object.prototype.toString.call(this.postForm.types[i]) === '[object Object]') {
                    this.postForm.types[i] = JSON.stringify(this.postForm.types[i])
                }
            }
            console.log(this.postForm)
        },
        addBlogAxios: async function (status) {
            for (let i = 0; i < this.postForm.types.length; i++) {
                if (Object.prototype.toString.call(this.postForm.types[i]) === '[object String]') {
                    this.postForm.types[i] = JSON.parse(this.postForm.types[i])
                }
            }
            const { data: res } = await this.$http.post('/blog', this.postForm);
            for (let i = 0; i < this.postForm.types.length; i++) {
                if (Object.prototype.toString.call(this.postForm.types[i]) === '[object Object]') {
                    this.postForm.types[i] = JSON.stringify(this.postForm.types[i])
                }
            }
            if (res.code ^ 200) {
                return this.$message({ showClose: true, message: res.msg, type: 'error' });
            }
            this.$message({ showClose: true, message: res.msg, type: 'success' });
            if (status) {
                await this.$router.push('/admin/blogs');
            }
            this.postDialogVisible = false;
        },
        addBlog: function (formName, status) {
            this.postForm.status = status
            this.postForm.userId = JSON.parse(window.localStorage.getItem('user')).id
            console.log(this.postForm)
            this.saveEditor(this.$refs.editor.d_value, this.$refs.editor.d_render)
            if (status) {
                this.$refs[formName].validate((valid) => {
                    if (!valid) {
                        return false;
                    }
                    this.addBlogAxios(status);
                })
            } else {
                this.checkSave = true
                this.addBlogAxios(status);
            }
        },
        handleClose (values, tag) {
            values.splice(values.indexOf(tag), 1);
        },
        showInput (vis) {
            if (vis === 'tag') {
                this.tagInputVisible = true;
                this.$nextTick(_ => {
                    this.$refs.saveTagInput.$refs.input.focus();
                });
            } else {
                this.cateInputVisible = true;
                this.$nextTick(_ => {
                    this.$refs.saveCateInput.$refs.input.focus();
                });
            }
        },
        handleInputConfirm (val) {
            if (val === 'tag') {
                const inputValue = this.tagInputValue.trim();
                this.tagInputVisible = false;
                this.tagInputValue = '';
                if (inputValue) {
                    this.postForm.tags.push(inputValue);
                    this.postForm.tags = _.uniq(this.postForm.tags)
                    console.log(this.postForm.tags)
                }
            } else {
                const inputValue = this.cateInputValue.trim();
                this.cateInputVisible = false;
                this.cateInputValue = '';
                if (inputValue) {
                    for (let i = 0; i < this.postForm.types.length; i++) {
                        if (Object.prototype.toString.call(this.postForm.types[i]) === '[object String]') {
                            this.postForm.types[i] = JSON.parse(this.postForm.types[i])
                        }
                    }
                    this.cateBoxList.forEach((val) => {
                        if (val.name === inputValue) {
                            this.postForm.types.push(val)
                        }
                    })

                    this.postForm.types.push({ name: inputValue });
                    this.postForm.types = _.uniqBy(this.postForm.types, 'name')
                    for (let i = 0; i < this.postForm.types.length; i++) {
                        if (Object.prototype.toString.call(this.postForm.types[i]) === '[object Object]') {
                            this.postForm.types[i] = JSON.stringify(this.postForm.types[i])
                        }
                    }
                    console.log(this.postForm.types)
                }
            }
        },
        handleAvatarSuccess (res, file) {
            console.log(res, file)
            this.imageUrl = URL.createObjectURL(file.raw);
        },
        beforeAvatarUpload (file) {
            const isJPG = file.type === 'image/jpeg';
            const isLt2M = file.size / 1024 / 1024 < 2;
            if (!isJPG) {
                this.$message.error('上传头像图片只能是 JPG 格式!');
            }
            if (!isLt2M) {
                this.$message.error('上传头像图片大小不能超过 2MB!');
            }
            return isJPG && isLt2M;
        },
        handleRemove (file, fileList) {
            console.log(file, fileList);
            this.fileList = fileList;
        },
        handlePictureCardPreview (file) {
            console.log(file.url)
            this.image_pre_vis = true;
        },
        saveEditor: function (value, render) {
            console.log(value, render)
            const regex = /<pre><div class="hljs"><code class="lang-/gi;
            render = render.replace(regex, '<pre><code class="line-numbers language-')
            render = render.replace(/<\/code><\/div><\/pre>/g, '</code></pre>')
            this.postForm.render = render
            console.log(render)
        },
        autoSave: _.debounce(function (val, old) {
            if (!_.eq(val, old)) {
                this.addBlog('postRef', false)
            }
        }, 5000)
    },
    created: function () {
        this.getBlog()
    },
    mounted: function () {
        window.onbeforeunload = function (e) {
            if (this.checkSave) {
                return;
            }
            e = e || window.event;
            // 兼容IE8和Firefox 4之前的版本
            if (e) {
                e.returnValue = '您是否确认离开此页面-您输入的数据可能不会被保存';
            }
            // Chrome, Safari, Firefox 4+, Opera 12+ , IE 9+
            return '您是否确认离开此页面-您输入的数据可能不会被保存';
        }
    },
    destroyed () {
        // 取消对事件的监听
        window.onbeforeunload = null;
    },
    beforeRouteLeave (to, from, next) {
        if (this.checkSave) {
            return next();
        }
        next(false)
        this.$confirm('当前页面数据未保存，确定要离开？', '提示', { type: 'warning' })
            .then(() => {
                next();
            })
    },
    computed: {
        disable: function () {
            return (list, len) => list.length >= len;
        }
    },
    watch: {
        'postForm.content': {
            handler (val, old) {
                if (this.postForm.status) {
                    return;
                }
                this.checkSave = true
                this.autoSave(val, old)
            },
            deep: true
        }
    }
}
</script>

<style lang='less' scoped>
#editor {
    //margin: auto;
    //width: 80%;
    height: 529px;
    border-bottom: #737373 solid 15px;

    ::v-deep .auto-textarea-input {
        font-family: "SF Mono", Menlo, "Ubuntu Mono", Consolas, "Courier New", "Microsoft Yahei", "Hiragino Sans GB", "WenQuanYi Micro Hei", sans-serif;
    }

    ::v-deep .markdown-body {
        border: none;
        border-radius: 0;

        pre {
            padding: 0;
        }

        a {
            color: #1abc9c;
        }

        a:hover {
            text-decoration: underline;
        }
    }

    ::v-deep .hljs {
        border-radius: 5px;

        code {
            font-size: 100%;
        }

        padding: 1em;
    }
}

::v-deep .el-upload-list--picture-card {
    display: inline-block;
    height: 148px;
}

::v-deep .el-textarea__inner {
    padding: 15px;
}

.avatar-uploader-icon {
    line-height: 148px;
}

//*******************************
.input-title {
    font-size: 20px;

    ::v-deep .el-input__count {
        font-size: 20px;
    }
}

.el-tag {
    margin-right: 10px;
}

.button-new-tag {
    height: 32px;
    line-height: 32px;
    padding-top: 0;
    padding-bottom: 0;
}

.input-new-tag {
    width: 118px;
    padding: 0 !important;
}

.cate-card {
    margin-top: 5px;
    position: inherit;

    ::v-deep .el-card__header {
        padding: 0 20px;
    }
}
</style>
